home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr47 / asmwin13.zip / VIDEO.ASM < prev    next >
Assembly Source File  |  1989-01-24  |  27KB  |  875 lines

  1. TITLE 'Direct Video Routines'
  2.  
  3. ;
  4. ; Author: David Bennett - Version 1.0 - Date: 11/9/88
  5. ;
  6. ; Version 1.1 - Added simple windowing routines, including clipping at
  7. ;               borders.  THomas Hill, Jan 1989
  8. ;
  9. ; This is a module of direct video writing routines for TASM.  Please see the
  10. ; file VIDEO.DOC for more information.  Examples of most routines are set forth
  11. ; in VIDDEMO.ASM.
  12. ;
  13. ; -Dave
  14. ;
  15. ; Jan 24, 1989 - Several changes had to be made in order to use my windowing
  16. ;                with the following video routines.  In particular, the 
  17. ;                screen saving and restoring procedures were not set up to
  18. ;                accept storage to/from diffrent data segments.  I changed
  19. ;                the parameters passed to include the segment of the stored
  20. ;                data.
  21. ;      
  22. ;                Thomas Hill
  23. ;
  24. IDEAL                   ; Uses TASM's IDEAL mode  (Get used to this!)
  25.  
  26. MODEL SMALL             ; Small memory model
  27.  
  28. INCLUDE 'VIDEO.INC'     ; Equates / Global decs etc...
  29.  
  30. ; ------
  31. ; Macros
  32. ; ------
  33.  
  34. MACRO   WaitRetrace
  35.     LOCAL   WaitNoH, WaitH, End
  36.     ;
  37.     ; This macro waits for the horizontial retrace signal from the
  38.     ; monitor before continuing. Interrupts should be disabled B4
  39.     ; calling this routine with CLI. Of course, make sure int's are
  40.     ; reenabled afterwards with STI.
  41.     ;
  42.     ; Modifies
  43.     ;       DX, AL
  44.     ;
  45.         mov     dx, 3DAh                ; CGA status register
  46.     WaitNoH:
  47.         in      al, dx                  ; Get 6845 Status
  48.         test    al,8                    ; Check vert retrace
  49.         jnz     End                     ;   In Progress? go
  50.         rcr     al,1                    ; Wait for end of
  51.         jc      WaitNoH                 ;   horizontial retrace
  52.     WaitH:
  53.         in      al, dx                  ; Get 6845 status again
  54.         rcr     al, 1                   ; Wait for horizontial
  55.         jnc     WaitH                   ;   retrace
  56.     End:
  57. ENDM
  58.  
  59.  
  60. DATASEG
  61.  
  62.     GLOBAL BaseOfScreen:WORD
  63.     GLOBAL SnowCheck:BYTE
  64.     GLOBAL VideoMode:BYTE
  65.  
  66.     BaseOfScreen    DW      CGASeg          ; Offset for current vid mode
  67.     SnowCheck       DB      0               ; Check for retrace 1/0
  68.     VideoMode       DB      0               ; Current BIOS INT 10 vid mode
  69.  
  70.  
  71. ; ---------
  72. ; Code area
  73. ; ---------
  74.  
  75. CODESEG
  76.  
  77. ; ----------------
  78. ; Video Procedures
  79. ; ----------------
  80.  
  81.     PROC MoveXY_DI
  82.     ;
  83.     ; This procedure moves to the offset indicated by an X & Y cusor
  84.     ; location.
  85.     ;
  86.     ; Input
  87.     ;       AH = Row
  88.     ;       AL = Column
  89.     ; Output
  90.     ;       DI = Memory Offset
  91.     ;
  92.         push    cx              ; Save CX
  93.         xor     cl, cl          ; Clear CL
  94.         mov     ch, ah          ; CX = Row * 256
  95.         dec     ch              ; CX = (Row - 1) {0-24 Based}
  96.         shr     cx, 1           ; CX = Row * 128
  97.         mov     di, cx          ; Store in DI
  98.         shr     di, 1           ; DI = Row * 64
  99.         shr     di, 1           ; DI = Row * 32
  100.         add     di, cx          ; DI = (Row * 128)+(Row * 32) {Row*160}
  101.         xor     ch, ch          ; Clear CH register
  102.         mov     cl, al          ; CX = Columns
  103.         dec     cx              ; Make 0-79
  104.         shl     cx, 1           ; Account for attribute
  105.         add     di, cx          ; DI = (Row * 160) + (Col * 2)
  106.         pop     cx              ; Restore CX register
  107.         ret
  108.  
  109.     ENDP MoveXY_DI
  110.  
  111.     PROC MoveXY_SI
  112.     ;
  113.     ; This procedure moves to the offset indicated by an X & Y cusor
  114.     ; location.
  115.     ;
  116.     ; Input
  117.     ;       AH = Row
  118.     ;       AL = Column
  119.     ; Output
  120.     ;       SI = Memory Offset - Points 1 byte beyond null of str displayed
  121.     ;
  122.  
  123.         push    cx              ; Save CX
  124.         xor     cl, cl          ; Clear CL
  125.         mov     ch, ah          ; CX = Row * 256
  126.         dec     ch              ; CX = (Row - 1) {0-24 Based}
  127.         shr     cx, 1           ; CX = Row * 128
  128.         mov     si, cx          ; Store in SI
  129.         shr     si, 1           ; SI = Row * 64
  130.         shr     si, 1           ; SI = Row * 32
  131.         add     si, cx          ; SI = (Row * 128)+(Row * 32) {Row*160}
  132.         xor     ch, ch          ; Clear CH register
  133.         mov     cl, al          ; CX = Columns
  134.         dec     cx              ; Make 0-79
  135.         shl     cx, 1           ; Account for attribute
  136.         add     si, cx          ; DI = (Row * 160) + (Col * 2)
  137.         pop     cx              ; Restore CX register
  138.         ret
  139.  
  140.     ENDP MoveXY_SI
  141.  
  142.     GLOBAL  EGAInstalled:PROC
  143.     PROC    EGAInstalled
  144.     ;
  145.     ; This procedure checks to see if the current adapter card is an
  146.     ; EGA.
  147.     ;
  148.     ; Output
  149.     ;       AL = 1 if EGA Adapter is found / 0 if not
  150.     ; Modified
  151.     ;       AX
  152.     ;
  153.         push    bx              ; Store used registers
  154.         push    cx
  155.         mov     ax, 1200h       ; BIOS INT 10 function 12h
  156.         mov     bx, 10h         ; sub-func 10h (Get EGA info)
  157.         mov     cx, 0FFFFh      ; lite all bits of CX
  158.         int     10h             ; call INT 10
  159.         xor     ax, ax          ; Clear AX reg
  160.         cmp     cx, 0FFFFh      ; If CX not modified by INT call
  161.         je      EI_Done         ;   then this is not an EGA
  162.         inc     AL              ; Increment AL to show this is EGA
  163.     EI_Done:
  164.         pop     cx              ; Restore regs
  165.         pop     bx
  166.         ret
  167.  
  168.     ENDP EGAInstalled
  169.  
  170.     GLOBAL  GetVideoMode:PROC
  171.     PROC    GetVideoMode
  172.     ;
  173.     ; This procedure checks the video mode and sets the BaseOfScreen
  174.     ; accordingly.  It also sets SnowCheck to 1 if adapter is a CGA.
  175.     ;
  176.     ; Output
  177.     ;       BaseOfScreen
  178.     ;       VideoMode
  179.     ;       SnowCheck
  180.     ; Uses
  181.     ;       EGAInstalled
  182.     ;
  183.         push    ax                      ; Store registers
  184.         push    di
  185.         push    ds
  186.         mov     ax, @data               ; Move DATASEG segment
  187.         mov     ds, ax                  ;   into DS registers
  188.         mov     di, CGASeg              ; move offset of CGA to DI
  189.         mov     ah, 0Fh                 ; INT 10 get vid mode func
  190.         int     10h                     ; get the video mode
  191.         xor     ah, ah                  ; clear the AH reg
  192.         mov     [VideoMode], al         ; place mode into VideoMode
  193.         cmp     al, 7                   ; Is this a mono screen?
  194.         jne     NotMono                 ; if not jump to NotMono
  195.         mov     di, MonoSeg             ; move offset of mono to DI
  196.         mov     [SnowCheck], 0          ; NEVER CHECK RETRACE ON MONO!
  197.         jmp     GVM_Done
  198.     NotMono:                                ; Process CGA/EGA/VGA adap.
  199.         call    EGAInstalled            ; Check for EGA adap.
  200.         rcr     al, 1                   ; Move bit 1 to carry flag
  201.         jc      GVM_Done                ; If EGA then no snow check
  202.         mov     [SnowCheck], 1          ; Not EGA so set snow check
  203.     GVM_Done:
  204.         mov     [BaseOfScreen], di      ; Move DI to base of screen
  205.         pop     ds                      ; Restore regs
  206.         pop     di
  207.         pop     ax
  208.         ret
  209.  
  210.     ENDP GetVideoMode
  211.  
  212.     GLOBAL  DWriteCH:PROC
  213.     PROC    DWriteCH
  214.     ;
  215.     ; Writes a character to the screen using direct memory access.
  216.     ;
  217.     ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  218.     ;
  219.     ; Input
  220.     ;       AH      Row on screen 1-25
  221.     ;       AL      Column on screen 1-80
  222.     ;       BH      Video Attribute
  223.     ;       BL      Character
  224.     ;       CX      Number of times
  225.     ; Output
  226.     ;       Screen memory (B000:0000 or 8000 CGA/MONO
  227.     ;
  228.         push    ax              ; Store the registers
  229.         push    cx
  230.         push    dx
  231.         push    es
  232.         push    di
  233.         call    MoveXY_DI       ; Set DI to row / column offset
  234.         mov     es, [BaseOfScreen]      ; Move screen seg to ES
  235.         mov     al, [SnowCheck]         ; Move snow check to al
  236.         rcr     al, 1           ; SnowCheck
  237.         jnc     DWC_NoWait      ; if no snowcheck goto FW_NoWait
  238.     DWC_Next:
  239.         cli                     ; Disable interrupts
  240.         WaitRetrace             ; Macro to wait for horiz retrace
  241.         mov     ax, bx          ; Move char/attr into AX
  242.         stosw                   ; Move char/attr to screen
  243.         sti                     ; Enable interrupts
  244.         loop    DWC_Next        ; Repeat CX times
  245.         jmp     DWC_Exit        ; Exit this routine
  246.     DWC_NoWait:
  247.         mov     ax, bx          ; Move char/attr into AX
  248.         rep     stosw           ; Move char/attr to screen CX times
  249.  
  250.     DWC_Exit:
  251.         pop     di              ; Restore the registers
  252.         pop     es
  253.         pop     dx
  254.         pop     cx
  255.         pop     ax
  256.         ret
  257.  
  258.     ENDP    DWriteCH
  259.  
  260.     GLOBAL  DWriteCHNA:PROC
  261.     PROC    DWriteCHNA
  262.     ;
  263.     ; Writes a character to the screen using direct memory access.
  264.     ; This procedure does not disturb current attr setting.
  265.     ;
  266.     ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  267.     ;
  268.     ; Input
  269.     ;       AH      Row on screen 1-25
  270.     ;       AL      Column on screen 1-80
  271.     ;       BL      Character
  272.     ;       CX      Number of times
  273.     ; Output
  274.     ;       Screen memory (B000:0000 or 8000 CGA/MONO
  275.     ;
  276.  
  277.         push    ax              ; Store the registers
  278.         push    cx
  279.         push    dx
  280.         push    es
  281.         push    di
  282.         call    MoveXY_DI       ; Set DI to row / column offset
  283.         mov     es, [BaseOfScreen]      ; Move screen seg to ES
  284.         mov     al, [SnowCheck]         ; Move snow check to al
  285.         rcr     al, 1           ; SnowCheck
  286.         jnc     DWCN_NoWait     ; if no snowcheck goto FW_NoWait
  287.     DWCN_Next:
  288.         cli                     ; Disable interrupts
  289.         WaitRetrace             ; Macro to wait for horiz retrace
  290.         mov     al, bl          ; Move char into al
  291.         stosb                   ; Move char to screen
  292.         sti                     ; Enable interrupts
  293.         inc     di              ; Skip over attr
  294.         loop    DWCN_Next       ; Repeat CX times
  295.         jmp     DWCN_Exit       ; Exit this routine
  296.     DWCN_NoWait:
  297.         mov     al, bl          ; Move char into AX
  298.     DWCN_NoWaitLoop:
  299.         stosb                   ; Move char to screen
  300.         inc     di              ; Skip over attr
  301.         loop    DWCN_NoWaitLoop ; Repeat CX times
  302.  
  303.     DWCN_Exit:
  304.         pop     di              ; Restore the registers
  305.         pop     es
  306.         pop     dx
  307.         pop     cx
  308.         pop     ax
  309.         ret
  310.  
  311.     ENDP    DWriteCHNA
  312.  
  313.     GLOBAL  DWriteStr:PROC
  314.     PROC    DWriteStr
  315.     ;
  316.     ; This procedure writes a null delimited string to the screen using
  317.     ; direct memory access.
  318.     ;
  319.     ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  320.     ;
  321.     ; Input
  322.     ;       DS:SI   Null terminated string to print
  323.     ;       AH      Row on screen 1-25
  324.     ;       AL      Column on screen 1-80
  325.     ;       BH      Video Attribute
  326.     ; Output
  327.     ;       Screen memory (B000:0000 or 8000 CGA/MONO
  328.     ; Modifies
  329.     ;       SI - Points 1 byte beyond null of str displayed
  330.     ;
  331.         push    ax              ; Store the registers
  332.         push    bx
  333.         push    cx
  334.         push    dx
  335.         push    es
  336.         push    di
  337.  
  338.         call    MoveXY_DI       ; Set DI to row / column offset
  339.         mov     es, [BaseOfScreen]      ; Move screen seg to ES
  340.         mov     cl, [SnowCheck]         ; Move snow check to al
  341.         cld                     ; Clear the direction flag
  342.         rcr     cl, 1           ; SnowCheck
  343.         mov     ah, bh          ; Place video attr in AH
  344.         jnc     DWS_NoWait      ; if no snowcheck goto DWS_NoWait
  345.     DWS_Next:
  346.         lodsb                   ; Get a character from source
  347.         or      al, al          ; Check for NULL
  348.         jz      DWS_Exit        ; If NULL then exit
  349.         mov     bx, ax          ; Store video word into BX
  350.         cli                     ; Disable interrupts
  351.         WaitRetrace             ; Macro to wait for horiz retrace
  352.         mov     ax, bx          ; Move word back to AX...
  353.         stosw                   ; Move word to screen
  354.         sti                     ; Enable interrupts
  355.         jmp     DWS_Next        ; Continue
  356.     DWS_NoWait:
  357.         lodsb                   ; Get a character from string
  358.         or      al, al          ; Check for NULL
  359.         jz      DWS_Exit        ; If NULL then exit
  360.         stosw                   ; Move word to screen
  361.         loop    DWS_NoWait      ; Continue
  362.     DWS_Exit:
  363.         pop     di              ; Restore the registers
  364.         pop     es
  365.         pop     dx
  366.         pop     cx
  367.         pop     bx
  368.         pop     ax
  369.         ret
  370.  
  371.     ENDP    DWriteStr
  372.  
  373.     GLOBAL  DWriteStrNA:PROC
  374.     PROC    DWriteStrNA
  375.     ;
  376.     ; This procedure writes a null delimited string to the screen using
  377.     ; direct memory access, attribute is not changed.
  378.     ;
  379.     ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  380.     ;
  381.     ; Input
  382.     ;       DS:SI   Null terminated string to print
  383.     ;       AH      Row on screen 1-25
  384.     ;       AL      Column on screen 1-80
  385.     ; Output
  386.     ;       Screen memory (B000:0000 or 8000 CGA/MONO)
  387.     ; Modifies
  388.     ;       SI - Points 1 byte beyond null of str displayed
  389.     ;
  390.         push    ax              ; Store the registers
  391.         push    bx
  392.         push    cx
  393.         push    dx
  394.         push    es
  395.         push    di
  396.  
  397.         call    MoveXY_DI       ; Set DI to screen offset pos
  398.         mov     es, [BaseOfScreen]      ; Move screen seg to ES
  399.         mov     cl, [SnowCheck]         ; Move snow check to cl
  400.         cld                     ; Clear the direction flag
  401.         rcr     cl, 1           ; SnowCheck
  402.         jnc     DWSN_NoWait     ; if no snowcheck goto DWSN_NoWait
  403.     DWSN_Next:
  404.         lodsb                   ; Get a character from source
  405.         or      al, al          ; Check for NULL
  406.         jz      DWSN_Exit       ; If NULL then exit
  407.         mov     bx, ax          ; Store video word into BX
  408.         cli                     ; Turn off interrupts
  409.         WaitRetrace             ; Macro - Waits for horiz retrace
  410.         mov     ax, bx          ; Move word back to AX...
  411.         stosb                   ; Move word to screen
  412.         sti                     ; Enable interrupts
  413.         inc     di              ; Skip the attribute.
  414.         jmp     DWSN_Next       ; Continue
  415.     DWSN_NoWait:
  416.         lodsb                   ; Get a character from string
  417.         or      al, al          ; Check for NULL
  418.         jz      DWSN_Exit       ; If NULL then exit
  419.         stosb                   ; Store the byte on screen
  420.         inc     di              ; Skip attribute byte
  421.         loop    DWSN_NoWait     ; Continue
  422.     DWSN_Exit:
  423.         pop     di              ; Restore the registers
  424.         pop     es
  425.         pop     dx
  426.         pop     cx
  427.         pop     bx
  428.         pop     ax
  429.         ret
  430.  
  431.     ENDP DWriteStrNA
  432.  
  433.     GLOBAL  DFillCH:PROC
  434.     PROC    DFillCH
  435.     ;
  436.     ; This procedure fills an area of the screen with the specified
  437.     ; character and attribute.
  438.     ;
  439.     ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  440.     ;
  441.     ; Input
  442.     ;       AH      = Top Row
  443.     ;       AL      = Left Column
  444.     ;       BH      = Number of rows
  445.     ;       BL      = Number of columns
  446.     ;       DH      = Attribute
  447.     ;       DL      = Character
  448.     ;
  449.         push    ax                      ; Store Registers
  450.         push    bx
  451.         push    cx
  452.         push    dx
  453.         push    es
  454.         push    di
  455.  
  456.                 jz      DFC_Exit                ; string won't fit
  457.         mov     es, [BaseOfScreen]      ; Move screen seg to ES
  458.         mov     cl, [SnowCheck]         ; Move snow check to CL
  459.  
  460.         cld                     ; Clear the direction flag
  461.         rcr     cl, 1           ; SnowCheck
  462.         mov     ch, 0           ; Clear CH
  463.         jnc     DFC_NoWait      ; if no snowcheck goto DFC_NoWait
  464.  
  465.     DFC_Top:
  466.         mov     cl, bl          ; Load the number of columns
  467.         call    MoveXY_DI       ; Set DI to screen offset pos
  468.         push    ax              ; Store Registers AX, BX
  469.         push    bx
  470.  
  471.     DFC_Next:
  472.         cli                     ; Turn off interrupts
  473.         push    dx              ; Store video word
  474.         WaitRetrace             ; Macro - Waits for horiz retrace
  475.         pop     dx              ; Restore video word
  476.         mov     ax, dx          ; Move word into AX
  477.         stosw                   ; Move word to screen
  478.         sti                     ; Enable interrupts
  479.         loop    DFC_Next        ; Continue
  480.  
  481.         pop     bx              ; Restore registers BX, AX
  482.         pop     ax
  483.         inc     ah              ; Next row
  484.         dec     bh              ; Decrement the number of rows done
  485.         or      bh, bh          ; Check Number of columns
  486.         jnz     DFC_Top         ; Do next column if not done
  487.         jmp     DFC_Exit        ; Exit routine
  488.  
  489.     DFC_NoWait:
  490.         mov     cl, bl          ; Load the number of columns
  491.         call    MoveXY_DI       ; Set DI to screen offset pos
  492.         push    ax              ; Store the char/attr
  493.         mov     ax, dx          ; Move char/attr into ax
  494.         rep     stosw           ; Thats it!
  495.         pop     ax              ; Restore the char/attr
  496.         inc     ah              ; Next row
  497.         dec     bh              ; Decrement number of rows done
  498.         or      bh, bh          ; Check number of columns
  499.         jnz     DFC_NoWait      ; Do next column
  500.  
  501.     DFC_Exit:
  502.         pop     di              ; Restore registers
  503.         pop     es
  504.         pop     dx
  505.         pop     cx
  506.         pop     bx
  507.         pop     ax
  508.         ret
  509.  
  510.     ENDP DFillCH
  511.  
  512.     GLOBAL  DFillCHNA:PROC
  513.     PROC    DFillCHNA
  514.     ;
  515.     ; This procedure fills an area of the screen with the specified
  516.     ; character. Attribute remains the same.
  517.     ;
  518.     ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  519.     ;
  520.     ; Input
  521.     ;       AH      = Top Row
  522.     ;       AL      = Left Column
  523.     ;       BH      = Number of rows
  524.     ;       BL      = Number of columns
  525.     ;       DL      = Character
  526.     ;
  527.         push    ax                      ; Store Registers
  528.         push    bx
  529.         push    cx
  530.         push    dx
  531.         push    es
  532.         push    di
  533.  
  534.         mov     es, [BaseOfScreen]      ; Move screen seg to ES
  535.         mov     cl, [SnowCheck]         ; Move snow check to CL
  536.  
  537.         cld                     ; Clear the direction flag
  538.         rcr     cl, 1           ; SnowCheck
  539.         mov     ch, 0           ; Clear CH
  540.         jnc     DFCN_NoWait     ; if no snowcheck goto DFCN_NoWait
  541.  
  542.     DFCN_Top:
  543.         mov     cl, bl          ; Load the number of columns
  544.         call    MoveXY_DI       ; Set DI to screen offset pos
  545.         push    ax              ; Store Registers AX, BX
  546.         push    bx
  547.  
  548.     DFCN_Next:
  549.         cli                     ; Turn off interrupts
  550.         push    dx              ; Save video word
  551.         WaitRetrace             ; Macro - Waits for horiz retrace
  552.         pop     dx              ; Restore video word
  553.         mov     al, dl          ; Move character into al
  554.         stosb                   ; Move word to screen
  555.         sti                     ; Enable interrupts
  556.         inc     di              ; Skip attr
  557.         loop    DFCN_Next       ; Continue
  558.  
  559.         pop     bx              ; Restore registers BX, AX
  560.         pop     ax
  561.         inc     ah              ; Next row
  562.         dec     bh              ; Decrement the number of rows done
  563.         or      bh, bh          ; Check Number of columns
  564.         jnz     DFCN_Top        ; Do next column if not done
  565.         jmp     DFCN_Exit       ; Exit routine
  566.  
  567.     DFCN_NoWait:
  568.         mov     cl, bl          ; Load the number of columns
  569.         call    MoveXY_DI       ; Set DI to screen offset pos
  570.         push    ax              ; Store the row/col info
  571.         mov     al, dl          ; Move char into ax
  572.     DFCN_NoWaitLoop:
  573.         stosb                   ; Thats it!
  574.         inc     di              ; Skip over attr
  575.         loop    DFCN_NoWaitLoop ; Loop for all columns
  576.         pop     ax              ; Restore the row/col info
  577.         inc     ah              ; Next row
  578.         dec     bh              ; Decrement number of rows done
  579.         or      bh, bh          ; Check number of columns
  580.         jnz     DFCN_NoWait     ; Do next column
  581.  
  582.     DFCN_Exit:
  583.         pop     di              ; Restore registers
  584.         pop     es
  585.         pop     dx
  586.         pop     cx
  587.         pop     bx
  588.         pop     ax
  589.         ret
  590.  
  591.     ENDP DFillCHNA
  592.  
  593.     GLOBAL  DFillAttr:PROC
  594.     PROC    DFillAttr
  595.     ;
  596.     ; This procedure fills an area of the screen with the specified
  597.     ; attribute. Character remains the same.
  598.     ;
  599.     ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  600.     ;
  601.     ; Input
  602.     ;       AH      = Top Row
  603.     ;       AL      = Left Column
  604.     ;       BH      = Number of rows
  605.     ;       BL      = Number of columns
  606.     ;       DH      = Attribute
  607.     ;
  608.         push    ax                      ; Store Registers
  609.         push    bx
  610.         push    cx
  611.         push    dx
  612.         push    es
  613.         push    di
  614.  
  615.         mov     es, [BaseOfScreen]      ; Move screen seg to ES
  616.         mov     cl, [SnowCheck]         ; Move snow check to CL
  617.  
  618.         cld                     ; Clear the direction flag
  619.         rcr     cl, 1           ; SnowCheck
  620.         mov     ch, 0           ; Clear CH
  621.         jnc     DFA_NoWait      ; if no snowcheck goto DFA_NoWait
  622.  
  623.     DFA_Top:
  624.         mov     cl, bl          ; Load the number of columns
  625.         call    MoveXY_DI       ; Set DI to screen offset pos
  626.         push    ax              ; Store Registers AX, BX
  627.         push    bx
  628.  
  629.     DFA_Next:
  630.         cli                     ; Turn off interrupts
  631.         push    dx              ; Save attribute in DH
  632.         WaitRetrace             ; Macro - Waits for horiz retrace
  633.         pop     dx              ; Restore attr
  634.         inc     di              ; Skip character
  635.         mov     al, dh          ; Move attr into al
  636.         stosb                   ; Move attr to screen
  637.         sti                     ; Enable interrupts
  638.         loop    DFA_Next        ; Continue
  639.  
  640.         pop     bx              ; Restore registers BX, AX
  641.         pop     ax
  642.         inc     ah              ; Next row
  643.         dec     bh              ; Decrement the number of rows done
  644.         or      bh, bh          ; Check Number of columns
  645.         jnz     DFA_Top         ; Do next column if not done
  646.         jmp     DFA_Exit        ; Exit routine
  647.  
  648.     DFA_NoWait:
  649.         mov     cl, bl          ; Load the number of columns
  650.         call    MoveXY_DI       ; Set DI to screen offset pos
  651.         push    ax              ; Store the row/col info
  652.         mov     al, dh          ; Move attr into ax
  653.     DFA_NoWaitLoop:
  654.         inc     di              ; Skip over character
  655.         stosb                   ; Thats it!
  656.         loop    DFA_NoWaitLoop  ; Loop for all columns
  657.         pop     ax              ; Restore the row/col info
  658.         inc     ah              ; Next row
  659.         dec     bh              ; Decrement number of rows done
  660.         or      bh, bh          ; Check number of columns
  661.         jnz     DFA_NoWait      ; Do next column
  662.  
  663.     DFA_Exit:
  664.         pop     di              ; Restore registers
  665.         pop     es
  666.         pop     dx
  667.         pop     cx
  668.         pop     bx
  669.         pop     ax
  670.         ret
  671.  
  672.     ENDP DFillAttr
  673.  
  674.     GLOBAL  StoreToMem:PROC
  675.     PROC    StoreToMem
  676.     ;
  677.     ; This procedure moves an image from the screen to the designated
  678.     ; memory area.
  679.     ;
  680.     ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  681.     ;
  682.     ; Input
  683.     ;       AH      = Top Row
  684.     ;       AL      = Left Column
  685.     ;       BH      = Number of rows
  686.     ;       BL      = Number of columns
  687.     ;       ES:DI   = Memory Destination
  688.     ; Modifies
  689.     ;       DI
  690.     ;
  691.         push    ax
  692.         push    bx
  693.         push    cx
  694.         push    dx
  695.         push    ds              ; Store registers
  696.         push    si
  697.  
  698.         mov cl, [SnowCheck]     ; Move snow check to CL
  699.         mov ds, [BaseOfScreen]  ; Move screen seg to DS mov cl,
  700.  
  701.         cld                     ; Clear the direction flag
  702.         rcr     cl, 1           ; SnowCheck
  703.         mov     ch, 0           ; Clear CH
  704.         jnc     STM_NoWait      ; if no snowcheck goto STM_NoWait
  705.  
  706.     STM_Top:
  707.         mov     cl, bl          ; Load the number of columns
  708.         call    MoveXY_SI       ; Set SI to screen offset pos
  709.         push    ax              ; Store row/column info
  710.         push    bx              ; Store number of row/columns info
  711.     STM_Next:
  712.         lodsw                   ; Get a char/word from screen
  713.         mov     bx, ax          ; Store video word into BX
  714.         cli                     ; Turn off interrupts
  715.         WaitRetrace             ; Macro - Waits for horiz retrace
  716.         mov     ax, bx          ; Move word back to AX...
  717.         stosw                   ; Move word to memory
  718.         sti                     ; Enable interrupts
  719.         loop    STM_Next        ; Continue
  720.         pop     bx              ; Restore number of row/columns info
  721.         pop     ax              ; Restore row/column info
  722.         inc     ah              ; Next row
  723.         dec     bh              ; Decrement the number of rows done
  724.         or      bh, bh          ; Check Number of columns
  725.         jnz     STM_Top         ; Do next column if not done
  726.         jmp     STM_Exit        ; Exit routine
  727.  
  728.     STM_NoWait:
  729.         mov     cl, bl          ; Load the number of columns
  730.         call    MoveXY_SI       ; Set SI to screen offset pos
  731.         rep     movsw           ; Thats it!
  732.         inc     ah              ; Next row
  733.         dec     bh              ; Decrement number of rows done
  734.         or      bh, bh          ; Check number of columns
  735.         jnz     STM_NoWait      ; Do next column
  736.  
  737.     STM_Exit:
  738.         pop     si
  739.         pop     ds
  740.         pop     dx
  741.         pop     cx
  742.         pop     bx
  743.         pop     ax
  744.         ret
  745.  
  746.     ENDP StoreToMem
  747.  
  748.     GLOBAL  StoreToScr:PROC
  749.     PROC    StoreToScr
  750.     ;
  751.     ; This procedure moves an image from memory to the designated
  752.     ; screen location.
  753.     ;
  754.     ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  755.     ;
  756.     ; Input
  757.     ;       AH      = Top Row
  758.     ;       AL      = Left Column
  759.     ;       BH      = Number of rows
  760.     ;       BL      = Number of columns
  761.         ;       DX      = Base of segment where image is stored
  762.     ;       SI      = Offset from DX to Memory Area of image
  763.     ; Modifies
  764.     ;       SI
  765.     ;
  766.         push    ax                      ; Store Registers
  767.         push    bx
  768.                 push    cx
  769.         push    dx
  770.         push    es
  771.         push    di
  772.  
  773.         mov     es, [BaseOfScreen]      ; Move screen seg to ES
  774.         mov     cl, [SnowCheck]         ; Move snow check to CL
  775.  
  776.                 mov     ds,dx           ; set up new data segment
  777.         cld                     ; Clear the direction flag
  778.         rcr     cl, 1           ; SnowCheck
  779.         mov     ch, 0           ; Clear CH
  780.         jnc     STS_NoWait      ; if no snowcheck goto STS_NoWait
  781.  
  782.     STS_Top:
  783.         mov     cl, bl          ; Load the number of columns
  784.         call    MoveXY_DI       ; Set DI to screen offset pos
  785.         push    ax              ; Store Registers AX, BX
  786.         push    bx
  787.  
  788.     STS_Next:
  789.         lodsw                   ; Get a char/word from memory
  790.         mov     bx, ax          ; Store video word into BX
  791.         cli                     ; Turn off interrupts
  792.         WaitRetrace             ; Macro - Waits for horiz retrace
  793.         mov     ax, bx          ; Move word back to AX...
  794.         stosw                   ; Move word to screen
  795.         sti                     ; Enable interrupts
  796.         loop    STS_Next        ; Continue
  797.  
  798.         pop     bx              ; Restore registers BX, AX
  799.         pop     ax
  800.         inc     ah              ; Next row
  801.         dec     bh              ; Decrement the number of rows done
  802.         or      bh, bh          ; Check Number of columns
  803.         jnz     STS_Top         ; Do next column if not done
  804.         jmp     STS_Exit        ; Exit routine
  805.  
  806.     STS_NoWait:
  807.         mov     cl, bl          ; Load the number of columns
  808.         call    MoveXY_DI       ; Set DI to screen offset pos
  809.         rep     movsw           ; Thats it!
  810.         inc     ah              ; Next row
  811.         dec     bh              ; Decrement number of rows done
  812.         or      bh, bh          ; Check number of columns
  813.         jnz     STS_NoWait      ; Do next column
  814.  
  815.     STS_Exit:
  816.         pop     di              ; Restore registers
  817.         pop     es
  818.         pop     dx
  819.         pop     cx
  820.         pop     bx
  821.         pop     ax
  822.         ret
  823.  
  824.     ENDP StoreToScr
  825.  
  826.     GLOBAL CursorOff:PROC
  827.     PROC   CursorOff
  828.     ;
  829.     ; This procedure simply turns the Cursor off
  830.     ;
  831.  
  832.         push    ax
  833.         push    bx
  834.         push    cx
  835.         push    dx
  836.         mov     ah, 03h         ; BIOS INT 10 func 3 (Get Cursor pos)
  837.         int     10h             ; Call INT 10
  838.         or      ch, 0100000b    ; Turn on cursor bit
  839.         mov     ah, 01h         ; BIOS INT 10 func 1 (Set cursor type)
  840.         int     10h             ; Call INT 10
  841.         pop     dx
  842.         pop     cx
  843.         pop     bx
  844.         pop     ax
  845.         ret
  846.     ENDP CursorOff
  847.  
  848.     GLOBAL CursorOn:PROC
  849.     PROC   CursorOn
  850.     ;
  851.     ; This procedure simply turns the Cursor on
  852.     ;
  853.         push    ax
  854.         push    bx
  855.         push    cx
  856.         push    dx
  857.         mov     ah, 03h         ; BIOS INT 10 func 3 (Get Cursor pos)
  858.         int     10h             ; Call INT 10
  859.         and     ch, 1011111b    ; Turn off cursor bit
  860.         mov     ah, 01h         ; BIOS INT 10 func 1 (Set cursor type)
  861.         int     10h             ; Call INT 10
  862.         pop     dx
  863.         pop     cx
  864.         pop     bx
  865.         pop     ax
  866.         ret
  867.  
  868.     ENDP CursorOn
  869.  
  870.  
  871. END ; Of Video.ASM
  872.  
  873.  
  874.  
  875.